

const VERSION = "2024-08-5.2";
// //MyESP_URL=
// //MY_staticSrcSRV=
//// for esp
// var MyESP_URL="http://sun_water70000.esp32.lan/";
var MyESP_URL="http://sun_water70000.esp32.lan/";
var MY_staticSrcSRV="http://op.lan:81/webpages/sun/";

const baseUrl="http://op.lan:81/cgi-bin/sun_water70000.sh";
const infoUrl=baseUrl+"?"+"json=info";
const heatUrl=baseUrl+"?"+"json=heat";
const heat75Url=baseUrl+"?"+"json=heat75";
const cancel_heatUrl=baseUrl+"?"+"json=cancel_heat";
const feedUrl=baseUrl+"?"+"json=feed";
const cancel_feedUrl=baseUrl+"?"+"json=cancel_feed";



(function () {
	let calc = function () {
		//获取文档的元素赋值给docElement保存
		let docElement = document.documentElement;
		//如果页面的宽度大于750px 那么让它等于750px 否则返回页面的宽度 最后赋值保存到定义的clientWidthValue
		let clientWidthValue = docElement.clientWidth > 750 ? 750 : docElement.clientWidth;
		if(clientWidthValue>docElement.clientHeight){
			clientWidthValue=parseInt(docElement.clientHeight/4*3);
		}
		//设置字体比例
		docElement.style.fontSize = 16 * (clientWidthValue / 375) + 'px';
		let btn = document.querySelector("button");
		//btn.style.fontSize= 20*(clientWidthValue/375)+'px';
	}
	calc();//调用函数
	window.addEventListener('resize', calc);//全局执行事件（自定义屏幕尺寸）
})();


(function () {
	let __mk_url = (pre, s) => {
		if (pre.endsWith("/")) {
			return pre + s
		} else if (pre == "" || pre === undefined || pre === null) {
			return s;
		}
		return pre + "/" + s
	}

	let setDefaultlist = [];
	let setDefault = () => {
		for (let i = 0; i < setDefaultlist.length; i++) {
			setDefaultlist[i].setDefault();
		}
	}

	let c = (s) => {
		return document.createElement(s);
	}

	let audioBox = c("div");
	audioBox.style.display = "none";
	let audio = c("audio");
	let audioSrc = c("source");
	audioSrc.src = __mk_url(MY_staticSrcSRV, "click.mp3");
	audioSrc.type = "audio/mpeg";
	audio.volume = 0.2;

	audio.appendChild(audioSrc);
	audioBox.appendChild(audio);


	let header = c("div");
	header.style.background = "white";

	let icon = c("img");
	icon.setAttribute("src", __mk_url(MY_staticSrcSRV, "favicon.ico"));

	icon.style.width = "4rem";
	icon.style.height = "4rem";
	icon.style.marginLeft = "0.5rem";
	icon.style.paddingTop = "1rem";

	let iconStatus = c("label");
	iconStatus.style.display = "inline-block";
	iconStatus.style.position = "absolute";
	iconStatus.style.zIndex = 9998;
	iconStatus.style.right = "5rem";
	iconStatus.style.top = "2rem";
	iconStatus.style.background = "lightgreen";
	iconStatus.style.marginLeft = "10px";
	iconStatus.style.padding = "0 25px 0 10px";
	iconStatus.style.color = "white";
	iconStatus.style.fontSize = "2rem";

	iconStatus.setDefault = () => {
		iconStatus.innerText = "Sun..";
	}

	//->
	setDefaultlist.push(iconStatus);

	iconStatus.update = (ok) => {
		if (ok) {
			iconStatus.innerText = "Sun..✌";
		} else {
			iconStatus.innerText = "Sun..X";
		}
	}

	let timeBox = c("label");
	timeBox.style.display = "inline-block";
	timeBox.style.position = "absolute";
	timeBox.style.zIndex = 9999;
	timeBox.style.right = "1rem";
	timeBox.style.top = "2rem";
	timeBox.style.fontSize = "2rem";
	timeBox.style.fontFamily = " monospace";


	let timeH = c("label");
	let timeSep = c("label");
	let timeM = c("label");
	timeBox.appendChild(timeH);
	timeBox.appendChild(timeSep);
	timeBox.appendChild(timeM);
	timeBox.setDefault = () => {
		timeH.innerText = "?";
		timeSep.innerText = ":";
		timeM.innerText = "?";
	}

	//->
	setDefaultlist.push(timeBox);

	timeBox.update = (s1, s2, s3) => {
		if (s1 != null) {
			timeH.innerText = s1;
		}
		if (s2 != null) {
			timeSep.innerText = s2;
		}
		if (s3 != null) {
			timeM.innerText = s3;
		}
	}


	header.appendChild(icon);
	document.body.appendChild(iconStatus);
	document.body.appendChild(timeBox);

	document.body.appendChild(header);

	////////////////////// height
	let heightBoxOuter1 = c("div");
	heightBoxOuter1.style.background = "yellow";
	heightBoxOuter1.style.marginTop = "0.5rem";
	let heightBox1 = c("div");
	heightBox1.style.margin = "0 5%";
	let height1 = c("label");
	let height2 = c("label");
	let height3 = c("label");
	let height4 = c("label");
	let hlabel = c("label");
	hlabel.style = "color:rgb(0, 167, 208);font-size:2rem; padding:0 1.5rem;";

	let heightList = [height1, height2, height3, height4];
	setDefaultlist.push(heightBox1);
	heightBox1.setDefault = () => {
		let _set = (h) => {
			h.innerText = "?";
			h.style.color = "white";
			// h.style.fontSize="3.5rem";
			return h.style;
		}
		// _set(height1).fontSize = "2.5rem";
		// _set(height2).fontSize = "3rem";
		// _set(height3).fontSize = "3.5rem";
		// _set(height4).fontSize = "4rem";
		_set(height1).fontSize = "2.5rem";
		_set(height2).fontSize = "2.8rem";
		_set(height3).fontSize = "3.1rem";
		_set(height4).fontSize = "3.4rem";
		hlabel.style.display = "none";
	}

	heightBox1.setH = (x, target_h, on) => {
		let _set_H = (x) => {
			heightList.forEach((h, i) => {
				h.innerText = "Y";
				if (i < x) {
					h.style.color = "rgb(0, 167, 208)";
				} else {
					h.style.color = "white";
				}
			})
		}

		if (x == -1) {
			heightBox1.setDefault();
		} else if (x >= 0 && x <= 4) {
			_set_H(x);
		} else {
			//
		}


		if (!on) {
			return;
		}
		if (target_h > 0) {
			hlabel.innerText = "→ 💧" + target_h;
			hlabel.style.display = "inline-block";
			setTimeout(() => {
				hlabel.style.display = "none";
			}, _G.fetch_interval / 2)
		}
	}



	let heightBoxOuter2 = c("div");
	heightBoxOuter2.style.background = "yellow";
	heightBoxOuter2.style.marginTop = "0.5rem";
	let heightBox2 = c("div");
	heightBox2.style.margin = "0 5%";
	let btnFeed = c("button");
	btnFeed.innerText = "上 水";
	btnFeed.style.background = "#00a7d0";
	btnFeed.style.color = "white";
	btnFeed.style.width = "60%";
	// btnFeed.style.margin="0 5% 0.5rem 5%";
	btnFeed.style.fontSize = "1.5rem";
	// btnFeed.style.border="2px double white";


	let btnCancelFeed = c("button");
	btnCancelFeed.innerText = "取消";
	btnCancelFeed.style = "font-size:0.8rem;background:#00a7d0;color:white;width:15%;margin:0 0 0.5rem 2rem";


	heightBox1.appendChild(height1);
	heightBox1.appendChild(height2);
	heightBox1.appendChild(height3);
	heightBox1.appendChild(height4);
	heightBox1.appendChild(hlabel);

	heightBoxOuter1.appendChild(heightBox1);
	heightBox2.appendChild(btnFeed);
	heightBox2.appendChild(btnCancelFeed);
	heightBoxOuter1.appendChild(heightBox2);

	document.body.appendChild(heightBoxOuter1);
	document.body.appendChild(heightBoxOuter2);

	///////////////////////temperature
	let temperatureBoxOuter = c("div");
	temperatureBoxOuter.style = "background:yellow; margin-top: 1rem;";
	let temperatureBox = c("div");
	temperatureBox.style = "background:yellow;margin:0 5%; padding-bottom:2px;";
	let tbox1 = c("div");
	let tbox1left = c("div");
	let tbox1right = c("div");
	tbox1left.style = "display:inline-block";
	tbox1right.style = "display:inline-block";
	let tbox2 = c("div");
	let tlabel1 = c("label");
	tlabel1.style = "color:red;font-size:3.5rem";
	let tlabel2 = c("label");
	tlabel2.style = "color:red;font-size:2rem";

	let tlabel3 = c("label");
	tlabel3.style = "color:red;font-size:2rem; padding:0 1.5rem;";

	let tlabel_time = c("label");
	tlabel_time.style = "color:gray;font-size:1rem; display:block;margin:0 0 0 3rem;";


	temperatureBox.setDefault = () => {
		tlabel1.innerText = "??";
		tlabel2.innerText = "℃";
		tlabel3.style.display = "none";
		tlabel_time.innerText = "";
	}

	temperatureBox.cal_heating_time = (t, tt, h) => {
		let _cal_ = (t, tt, h) => {
			const h_to_v = [0, 0.06, 0.12, 0.18, 0.24];
			//TODO
			// (国际单位 立方米=1000L).  240L ,一般的容量在 80~620(L)之间
			if (h <= 0 || h > 4) {
				return -1;
			}
			return 2800.0 * h_to_v[h] * (tt - t);
		}


		if (t < 0 || tt < 0 || h < 0) {
			return;
		}


		if (h == 0) {
			h = 1;
		}

		let heatingSec = _cal_(t, tt, h);
		let time_sec = parseInt(heatingSec);
		let time_m = parseInt(time_sec / 60);
		let time_h = parseInt(time_m / 60);
		let s = "";

		if (time_m > 0) {
			time_sec = time_sec % 60;
			if (time_h > 0) {
				time_m = time_m % 60
			}
		}


		s = "加热需要 " + time_h + ':' + time_m + ":" + time_sec;
		// console.log(heatingSec);

		tlabel_time.innerText = s;


	}


	temperatureBox.setT = (t, tt, h, on) => {
		tlabel1.innerText = parseInt(t);
		if (on && (tt > 0)) {
			tlabel3.innerText = "→☀" + tt + "℃";
			tlabel3.style.display = "inline-block";
			setTimeout(() => {
				tlabel3.style.display = "none";
			}, _G.fetch_interval / 2);
			temperatureBox.cal_heating_time(t, tt, h);
		} else {
			tlabel_time.innerText = "";
		}
	}

	setDefaultlist.push(temperatureBox);
	temperatureBox.appendChild(tbox1);
	tbox1.appendChild(tbox1left);
	tbox1.appendChild(tbox1right);
	tbox1left.appendChild(tlabel1);
	tbox1left.appendChild(tlabel2);
	tbox1right.appendChild(tlabel3);
	tbox1right.appendChild(tlabel_time);
	temperatureBoxOuter.appendChild(temperatureBox)
	document.body.appendChild(temperatureBoxOuter);

	let btnHeat = c("button");
	btnHeat.innerText = "加 热🔥";
	btnHeat.style.background = "red";
	btnHeat.style.color = "white";
	btnHeat.style.width = "40%";
	// btnFeed.style.margin="0 5% 0.5rem 5%";
	btnHeat.style.fontSize = "1.5rem";
	// btnFeed.style.border="2px double white";

	let btnHeat75 = c("button");
	btnHeat75.innerText = "75℃";
	btnHeat75.style.background = "red";
	btnHeat75.style.marginLeft = "2%";
	btnHeat75.style.color = "white";
	btnHeat75.style.width = "18%";
	// btnFeed.style.margin="0 5% 0.5rem 5%";
	btnHeat75.style.fontSize = "1.5rem";
	// btnFeed.style.border="2px double white";


	let btnCancelHeat = c("button");
	btnCancelHeat.innerText = "取消";
	btnCancelHeat.style = "font-size:0.8rem;background:red;color:white;width:15%;margin:0 0 0.5rem 2rem";


	tbox2.appendChild(btnHeat);
	tbox2.appendChild(btnHeat75);
	tbox2.appendChild(btnCancelHeat);
	temperatureBox.appendChild(tbox2);

	let infoBox = c("div");
	infoBox.style = "background:yellow;padding-left:5%";
	let infoLabel = c("pre");
	infoLabel.style.marginTop = "0.3rem";
	infoLabel.innerText = "    \n";
	infoBox.appendChild(infoLabel);
	document.body.appendChild(infoBox);

	let echartBox = c("div");
	echartBox.id="echart_block";
	echartBox.style="width: 100%;height:350px;";
	document.body.appendChild(echartBox);


	let debugBox = c("div");
	debugBox.style.marginTop = "0.5rem;display:none;";
	let debugLabel = c("pre");
	debugLabel.style = "font-size:0.6rem";
	debugBox.setDefault = () => {
		debugBox.style.display = "none";
		debugLabel.innerText = "";
	}

	debugBox.update = (j) => {
		let s = "VERSION : " + VERSION + "\n";
		let v = null;
		for (let k in j) {
			if (k.startsWith("rrr")) {
				v = j[k] / 1000 + "k";
			} else {
				v = j[k];
			}
			s += k + " : " + v + "\n";
			debugLabel.innerText = s;
		}
		debugBox.style.display = "block";
	}

	debugBox.appendChild(debugLabel);
	document.body.appendChild(debugBox);

	/////////////////////////
	let _G = {};
	if (MyESP_URL === null || MyESP_URL === undefined || MyESP_URL == "") {
		_G.preURL = "http://sun_water70000.esp32.lan/";
	} else {
		_G.preURL = MyESP_URL;
	}

	_G.tick = null;
	_G.fetch_interval = 3000;
	_G.handler_updateTimeBox = null;
	_G.handler_fetch = null;
	_G.handler_resumeWorld = null;
	_G.handler_closeWorld = null;
	_G.Hour = null;
	_G.min = null;
	_G.H = null;
	_G.targetH = null;
	_G.feeding = false;
	_G.T = null;
	_G.targetT = null;
	_G.heating = false;
	_G.fetchErrorCount = 0;
	_G.second = 0;
	_G.debugModeCount = 0;
	_G.debugMode = false;

	_G.stopTimeBox = () => {
		if (_G.handler_updateTimeBox != null) {
			clearInterval(_G.handler_updateTimeBox);
		}
		_G.handler_updateTimeBox = null;
		timeBox.setDefault();
	}

	_G.updateTimeBox = () => {
		_G.stopTimeBox();
		_G.handler_updateTimeBox = setInterval(() => {
			let sep = ":";
			if (_G.second % 2 == 0) {
				sep = " ";
			}
			timeBox.update(_G.Hour, sep, _G.Min);
			_G.second++;
		}, 1000)
	}

	_G.updateHT = () => {
		heightBox1.setH(_G.H, _G.targetH, _G.feeding);
		temperatureBox.setT(_G.T, _G.targetT, _G.H, _G.heating);
	}



	_G.fetch = (u, abortContrl) => {
		fetch(u, {
			method: "GET",
			cache: "no-store",
			keepalive: true,
			signal: abortContrl.signal
		}).then(
			(data) => {
				return data.json();
			}).then((j) => {
				if (j.error == 0) {
					if (_G.debugMode) {
						debugBox.update(j);
					}
					_G.Hour = j["time"].slice(0, 2);
					_G.Min = j["time"].slice(3, 5);

					_G.H = j.height;
					_G.targetH = j.target_h;

					if (j.heating == "ON") {
						_G.heating = true;
					} else {
						_G.heating = false;
					}

					if (j.feeding == "ON") {
						_G.feeding = true;
					} else {
						_G.feeding = false;
					}

					_G.T = j.temperature;
					_G.targetT = j.target_t;

					_G.updateHT();
					iconStatus.update(true);
					_G.fetchErrorCount = 0;
				} else {
					console.log("[E] fetch error : ", j.error);
					_G.fetchErrorCount++;
					iconStatus.update(false);
					if (_G.fetchErrorCount % 3 == 0) {
						setDefault();
					}
				}
			}).catch((e) => {
				console.log("[E] catch fetch error::", e);
				_G.fetchErrorCount++;
				iconStatus.update(false);
				if (_G.fetchErrorCount % 3 == 0) {
					setDefault();
				}
			})
	}

	_G.tick=() => {
		// const url = __mk_url(_G.preURL, "sun_water_info.json");
		let abortContrl = new AbortController();
		setTimeout(function () {
			abortContrl.abort();
		}, _G.fetch_interval + 100);
		iconStatus.setDefault();
		_G.fetch(infoUrl, abortContrl);
	};

	_G.main = () => {
		// main
		_G.updateTimeBox();
		_G.tick();
		_G.handler_fetch = setInterval(_G.tick, _G.fetch_interval)
		//main end		
	}

	_G.resumeWorld = () => {
		if (_G.handler_closeWorld != null) {
			clearTimeout(_G.handler_closeWorld);
			_G.handler_closeWorld = null;
		}

		if (_G.handler_resumeWorld != null) {
			clearTimeout(_G.handler_resumeWorld);
			_G.handler_resumeWorld = null;
			return true;
		} else {
			_G.main();
			return false;
		}


	}

	_G.stopTheWorld = () => {
		_G.handler_resumeWorld = setTimeout(() => {
			_G.handler_resumeWorld = null;
			clearInterval(_G.handler_fetch);
			_G.stopTimeBox();
			setDefault();
		}, _G.fetch_interval * 2);

		_G.handler_closeWorld = setTimeout(() => {
			window.opener = null;
			window.open('', '_self');
			window.close();
		}, 20000);
	}

	////////////event
	window.onblur = () => {
		_G.stopTheWorld();
	}

	window.onfocus = () => {
		_G.resumeWorld();
	}

	////
	icon.addEventListener("click", () => {
		_G.debugModeCount++;
		console.log("click to debug ", _G.debugModeCount);
		if (_G.debugModeCount > 3) {
			_G.debugMode = true;
		} else {
			_G.debugMode = false;
			debugBox.setDefault();
		}

		setTimeout((c) => {
			if (c == _G.debugModeCount) {
				_G.debugModeCount = 0;
			}
		}, 1100, _G.debugModeCount)
	});

	let clickAction = (url) => {
		audio.play();
		let abortContrl = new AbortController();
		_G.fetch(url, abortContrl);
	}

	btnFeed.addEventListener("click", () => {
		// const url = __mk_url(_G.preURL, "sun_water_feed");
		clickAction(feedUrl);
	});

	btnCancelFeed.addEventListener("click", () => {
		// const url = __mk_url(_G.preURL, "sun_water_cancel_feed");
		clickAction(cancel_feedUrl);
	});

	btnHeat.addEventListener("click", () => {
		// const url = __mk_url(_G.preURL, "sun_water_heat");
		clickAction(heatUrl);
	});

	btnHeat75.addEventListener("click", () => {
		// const url = __mk_url(_G.preURL, "sun_water_heat");
		clickAction(heat75Url);
	});

	btnCancelHeat.addEventListener("click", () => {
		// const url = __mk_url(_G.preURL, "sun_water_cancel_heat");
		clickAction(cancel_heatUrl);
	});

	setDefault();
	_G.main();
})();





